package com.stillcoolme.basic;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

public class NonBlockingFileUploader {

    // 模拟文件上传方法
    private static boolean uploadFile(File file) {
        try {
            Thread.sleep((long) (Math.random() * 3000));
            return Math.random() > 0.1;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    public static CompletableFuture<List<UploadResult>> uploadFilesAsync(List<File> files) {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(4);

        // 为每个文件创建上传任务
        List<CompletableFuture<UploadResult>> uploadFutures = files.stream()
                .map(file -> CompletableFuture.supplyAsync(() -> {
                    long start = System.currentTimeMillis();
                    boolean success = uploadFile(file);
                    long duration = System.currentTimeMillis() - start;
                    return new UploadResult(file.getName(), success, duration);
                }, executor))
                .collect(Collectors.toList());

        // 组合所有Future
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                uploadFutures.toArray(new CompletableFuture[0])
        );

        // 当所有任务完成时，收集结果
        CompletableFuture<List<UploadResult>> resultFuture = allFutures.thenApply(v ->
                uploadFutures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList())
        );

        // 关闭线程池(当所有任务完成后)
        resultFuture.whenComplete((results, ex) -> executor.shutdown());

        return resultFuture;
    }


    public static boolean uploadTask() {
        // 准备文件列表
        List<File> files = Arrays.asList(
                new File("file1.txt"),
                new File("file2.txt"),
                new File("file3.txt")
        );

        // 异步上传，立即返回
        System.out.println("开始异步上传文件...");
        CompletableFuture<List<UploadResult>> uploadFuture = uploadFilesAsync(files);
        System.out.println("上传任务已提交，继续执行其他操作...");

        // 模拟其他工作
        doOtherWork();

        // 稍后获取结果(非阻塞方式)
        uploadFuture.thenAccept(results -> {
            System.out.println("\n所有文件上传完成！结果如下：");
            results.forEach(result ->
                    System.out.printf("文件 %s 上传%s, 耗时 %d 毫秒%n",
                            result.getFileName(),
                            result.isSuccess() ? "成功" : "失败",
                            result.getTimeTaken())
            );
        });

        return true;
    }

    public static void main(String[] args) {
        boolean result = uploadTask();
        System.out.println("上传任务接口拿到结果了：" + result);



        // 防止主线程退出(仅用于演示)
        try { Thread.sleep(5000); } catch (InterruptedException e) {}

    }

    private static void doOtherWork() {
        System.out.println("执行其他任务中...");
    }

    static class UploadResult {
        private final String fileName;
        private final boolean success;
        private final long timeTaken;

        public UploadResult(String fileName, boolean success, long timeTaken) {
            this.fileName = fileName;
            this.success = success;
            this.timeTaken = timeTaken;
        }

        public String getFileName() { return fileName; }
        public boolean isSuccess() { return success; }
        public long getTimeTaken() { return timeTaken; }
    }
}